// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   AnnotatedElementUtils.java

package org.springframework.core.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.*;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.*;

// Referenced classes of package org.springframework.core.annotation:
//			AnnotationAttributes, AnnotationUtils

public class AnnotatedElementUtils
{
	private static class MergedAnnotationAttributesProcessor
		implements Processor
	{

		private final String annotationName;
		private final boolean classValuesAsString;
		private final boolean nestedAnnotationsAsMap;

		public AnnotationAttributes process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth)
		{
			boolean found = annotation.annotationType().getName().equals(annotationName);
			return found ? AnnotationUtils.getAnnotationAttributes(annotatedElement, annotation, classValuesAsString, nestedAnnotationsAsMap, true) : null;
		}

		public void postProcess(AnnotatedElement element, Annotation annotation, AnnotationAttributes attributes)
		{
			annotation = AnnotationUtils.synthesizeAnnotation(annotation, element);
			Class targetAnnotationType = attributes.annotationType();
			Iterator iterator = AnnotationUtils.getAttributeMethods(annotation.annotationType()).iterator();
			do
			{
				if (!iterator.hasNext())
					break;
				Method attributeMethod = (Method)iterator.next();
				String attributeName = attributeMethod.getName();
				String aliasedAttributeName = AnnotationUtils.getAliasedAttributeName(attributeMethod, targetAnnotationType);
				if (StringUtils.hasText(aliasedAttributeName) && attributes.containsKey(aliasedAttributeName))
					overrideAttribute(element, annotation, attributes, attributeName, aliasedAttributeName);
				else
				if (!"value".equals(attributeName) && attributes.containsKey(attributeName))
					overrideAttribute(element, annotation, attributes, attributeName, attributeName);
			} while (true);
		}

		private void overrideAttribute(AnnotatedElement element, Annotation annotation, AnnotationAttributes attributes, String sourceAttributeName, String targetAttributeName)
		{
			Object value = AnnotationUtils.getValue(annotation, sourceAttributeName);
			Object adaptedValue = AnnotationUtils.adaptValue(element, value, classValuesAsString, nestedAnnotationsAsMap);
			attributes.put(targetAttributeName, adaptedValue);
		}

		public volatile void postProcess(AnnotatedElement annotatedelement, Annotation annotation, Object obj)
		{
			postProcess(annotatedelement, annotation, (AnnotationAttributes)obj);
		}

		public volatile Object process(AnnotatedElement annotatedelement, Annotation annotation, int i)
		{
			return process(annotatedelement, annotation, i);
		}

		MergedAnnotationAttributesProcessor(String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
		{
			this.annotationName = annotationName;
			this.classValuesAsString = classValuesAsString;
			this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;
		}
	}

	private static abstract class SimpleAnnotationProcessor
		implements Processor
	{

		public final void postProcess(AnnotatedElement annotatedelement, Annotation annotation1, Object obj)
		{
		}

		private SimpleAnnotationProcessor()
		{
		}

	}

	private static interface Processor
	{

		public abstract Object process(AnnotatedElement annotatedelement, Annotation annotation, int i);

		public abstract void postProcess(AnnotatedElement annotatedelement, Annotation annotation, Object obj);
	}


	private static final Boolean CONTINUE = null;

	public AnnotatedElementUtils()
	{
	}

	public static Set getMetaAnnotationTypes(AnnotatedElement element, Class annotationType)
	{
		Assert.notNull(annotationType, "annotationType must not be null");
		return getMetaAnnotationTypes(element, annotationType.getName());
	}

	public static Set getMetaAnnotationTypes(AnnotatedElement element, String annotationName)
	{
		Assert.notNull(element, "AnnotatedElement must not be null");
		Assert.hasText(annotationName, "annotationName must not be null or empty");
		Set types = new LinkedHashSet();
		try
		{
			Annotation annotation = AnnotationUtils.getAnnotation(element, annotationName);
			if (annotation != null)
				searchWithGetSemantics(annotation.annotationType(), annotationName, new SimpleAnnotationProcessor(types) {

					final Set val$types;

					public Object process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth)
					{
						types.add(annotation.annotationType().getName());
						return AnnotatedElementUtils.CONTINUE;
					}

			
			{
				types = set;
				super();
			}
				}, new HashSet(), 1);
		}
		catch (Throwable ex)
		{
			AnnotationUtils.rethrowAnnotationConfigurationException(ex);
			throw new IllegalStateException((new StringBuilder()).append("Failed to introspect annotations on ").append(element).toString(), ex);
		}
		return types.isEmpty() ? null : types;
	}

	public static boolean hasMetaAnnotationTypes(AnnotatedElement element, String annotationName)
	{
		Assert.notNull(element, "AnnotatedElement must not be null");
		Assert.hasText(annotationName, "annotationName must not be null or empty");
		return Boolean.TRUE.equals(searchWithGetSemantics(element, annotationName, new SimpleAnnotationProcessor(annotationName) {

			final String val$annotationName;

			public Boolean process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth)
			{
				boolean found = annotation.annotationType().getName().equals(annotationName);
				return !found || metaDepth <= 0 ? AnnotatedElementUtils.CONTINUE : Boolean.TRUE;
			}

			public volatile Object process(AnnotatedElement annotatedelement, Annotation annotation, int i)
			{
				return process(annotatedelement, annotation, i);
			}

			
			{
				annotationName = s;
				super();
			}
		}));
	}

	public static boolean isAnnotated(AnnotatedElement element, String annotationName)
	{
		Assert.notNull(element, "AnnotatedElement must not be null");
		Assert.hasText(annotationName, "annotationName must not be null or empty");
		return Boolean.TRUE.equals(searchWithGetSemantics(element, annotationName, new SimpleAnnotationProcessor(annotationName) {

			final String val$annotationName;

			public Boolean process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth)
			{
				boolean found = annotation.annotationType().getName().equals(annotationName);
				return found ? Boolean.TRUE : AnnotatedElementUtils.CONTINUE;
			}

			public volatile Object process(AnnotatedElement annotatedelement, Annotation annotation, int i)
			{
				return process(annotatedelement, annotation, i);
			}

			
			{
				annotationName = s;
				super();
			}
		}));
	}

	public static Annotation getMergedAnnotation(AnnotatedElement element, Class annotationType)
	{
		AnnotationAttributes attributes = getMergedAnnotationAttributes(element, annotationType);
		return attributes == null ? null : AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element);
	}

	public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, Class annotationType)
	{
		Assert.notNull(annotationType, "annotationType must not be null");
		return getMergedAnnotationAttributes(element, annotationType.getName());
	}

	/**
	 * @deprecated Method getAnnotationAttributes is deprecated
	 */

	public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement element, String annotationName)
	{
		return getMergedAnnotationAttributes(element, annotationName);
	}

	public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, String annotationName)
	{
		return getMergedAnnotationAttributes(element, annotationName, false, false);
	}

	/**
	 * @deprecated Method getAnnotationAttributes is deprecated
	 */

	public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement element, String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
	{
		return getMergedAnnotationAttributes(element, annotationName, classValuesAsString, nestedAnnotationsAsMap);
	}

	public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
	{
		AnnotationAttributes attributes = (AnnotationAttributes)searchWithGetSemantics(element, annotationName, new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap));
		AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap);
		return attributes;
	}

	public static Annotation findMergedAnnotation(AnnotatedElement element, Class annotationType)
	{
		Assert.notNull(annotationType, "annotationType must not be null");
		return findMergedAnnotation(element, annotationType.getName());
	}

	public static Annotation findMergedAnnotation(AnnotatedElement element, String annotationName)
	{
		AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationName, false, false);
		return attributes == null ? null : AnnotationUtils.synthesizeAnnotation(attributes, attributes.annotationType(), element);
	}

	public static AnnotationAttributes findMergedAnnotationAttributes(AnnotatedElement element, String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
	{
		AnnotationAttributes attributes = (AnnotationAttributes)searchWithFindSemantics(element, annotationName, new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap));
		AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap);
		return attributes;
	}

	public static MultiValueMap getAllAnnotationAttributes(AnnotatedElement element, String annotationName)
	{
		return getAllAnnotationAttributes(element, annotationName, false, false);
	}

	public static MultiValueMap getAllAnnotationAttributes(AnnotatedElement element, String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap)
	{
		MultiValueMap attributesMap = new LinkedMultiValueMap();
		searchWithGetSemantics(element, annotationName, new SimpleAnnotationProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap, attributesMap) {

			final String val$annotationName;
			final boolean val$classValuesAsString;
			final boolean val$nestedAnnotationsAsMap;
			final MultiValueMap val$attributesMap;

			public Void process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth)
			{
				boolean found = annotation.annotationType().getName().equals(annotationName);
				if (found)
				{
					AnnotationAttributes annotationAttributes = AnnotationUtils.getAnnotationAttributes(annotation, classValuesAsString, nestedAnnotationsAsMap);
					java.util.Map.Entry entry;
					for (Iterator iterator = annotationAttributes.entrySet().iterator(); iterator.hasNext(); attributesMap.add(entry.getKey(), entry.getValue()))
						entry = (java.util.Map.Entry)iterator.next();

				}
				return null;
			}

			public volatile Object process(AnnotatedElement annotatedelement, Annotation annotation, int i)
			{
				return process(annotatedelement, annotation, i);
			}

			
			{
				annotationName = s;
				classValuesAsString = flag;
				nestedAnnotationsAsMap = flag1;
				attributesMap = multivaluemap;
				super();
			}
		});
		return attributesMap.isEmpty() ? null : attributesMap;
	}

	private static Object searchWithGetSemantics(AnnotatedElement element, String annotationName, Processor processor)
	{
		return searchWithGetSemantics(element, annotationName, processor, ((Set) (new HashSet())), 0);
		Throwable ex;
		ex;
		AnnotationUtils.rethrowAnnotationConfigurationException(ex);
		throw new IllegalStateException((new StringBuilder()).append("Failed to introspect annotations on ").append(element).toString(), ex);
	}

	private static Object searchWithGetSemantics(AnnotatedElement element, String annotationName, Processor processor, Set visited, int metaDepth)
	{
		Assert.notNull(element, "AnnotatedElement must not be null");
		Assert.hasText(annotationName, "annotationName must not be null or empty");
		if (!visited.add(element))
			break MISSING_BLOCK_LABEL_153;
		List declaredAnnotations;
		Object result;
		declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations());
		result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations, annotationName, processor, visited, metaDepth);
		if (result != null)
			return result;
		List inheritedAnnotations = new ArrayList();
		Annotation aannotation[] = element.getAnnotations();
		int i = aannotation.length;
		for (int j = 0; j < i; j++)
		{
			Annotation annotation = aannotation[j];
			if (!declaredAnnotations.contains(annotation))
				inheritedAnnotations.add(annotation);
		}

		result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations, annotationName, processor, visited, metaDepth);
		if (result != null)
			return result;
		break MISSING_BLOCK_LABEL_153;
		Exception ex;
		ex;
		AnnotationUtils.handleIntrospectionFailure(element, ex);
		return null;
	}

	private static Object searchWithGetSemanticsInAnnotations(AnnotatedElement annotatedElement, List annotations, String annotationName, Processor processor, Set visited, int metaDepth)
	{
		for (Iterator iterator = annotations.iterator(); iterator.hasNext();)
		{
			Annotation annotation = (Annotation)iterator.next();
			if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation) && (annotation.annotationType().getName().equals(annotationName) || metaDepth > 0))
			{
				Object result = processor.process(annotatedElement, annotation, metaDepth);
				if (result != null)
					return result;
			}
		}

		for (Iterator iterator1 = annotations.iterator(); iterator1.hasNext();)
		{
			Annotation annotation = (Annotation)iterator1.next();
			if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation))
			{
				Object result = searchWithGetSemantics(annotation.annotationType(), annotationName, processor, visited, metaDepth + 1);
				if (result != null)
				{
					processor.postProcess(annotatedElement, annotation, result);
					return result;
				}
			}
		}

		return null;
	}

	private static Object searchWithFindSemantics(AnnotatedElement element, String annotationName, Processor processor)
	{
		return searchWithFindSemantics(element, annotationName, processor, ((Set) (new HashSet())), 0);
		Throwable ex;
		ex;
		AnnotationUtils.rethrowAnnotationConfigurationException(ex);
		throw new IllegalStateException((new StringBuilder()).append("Failed to introspect annotations on ").append(element).toString(), ex);
	}

	private static Object searchWithFindSemantics(AnnotatedElement element, String annotationName, Processor processor, Set visited, int metaDepth)
	{
		Assert.notNull(element, "AnnotatedElement must not be null");
		Assert.hasText(annotationName, "annotationName must not be null or empty");
		if (!visited.add(element))
			break MISSING_BLOCK_LABEL_490;
		Annotation annotations[];
		Annotation aannotation[];
		int i;
		int j;
		annotations = element.getDeclaredAnnotations();
		aannotation = annotations;
		i = aannotation.length;
		j = 0;
_L1:
		Object result;
		if (j >= i)
			break MISSING_BLOCK_LABEL_113;
		Annotation annotation = aannotation[j];
		if (AnnotationUtils.isInJavaLangAnnotationPackage(annotation) || !annotation.annotationType().getName().equals(annotationName) && metaDepth <= 0)
			break MISSING_BLOCK_LABEL_107;
		result = processor.process(element, annotation, metaDepth);
		if (result != null)
			return result;
		j++;
		  goto _L1
		aannotation = annotations;
		i = aannotation.length;
		j = 0;
_L2:
		if (j >= i)
			break MISSING_BLOCK_LABEL_197;
		Annotation annotation = aannotation[j];
		if (AnnotationUtils.isInJavaLangAnnotationPackage(annotation))
			break MISSING_BLOCK_LABEL_191;
		result = searchWithFindSemantics(((AnnotatedElement) (annotation.annotationType())), annotationName, processor, visited, metaDepth + 1);
		if (result == null)
			break MISSING_BLOCK_LABEL_191;
		processor.postProcess(annotation.annotationType(), annotation, result);
		return result;
		j++;
		  goto _L2
		Method method;
		Object result;
		if (!(element instanceof Method))
			break MISSING_BLOCK_LABEL_372;
		method = (Method)element;
		Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
		result = searchWithFindSemantics(((AnnotatedElement) (resolvedMethod)), annotationName, processor, visited, metaDepth);
		if (result != null)
			return result;
		Class ifcs[] = method.getDeclaringClass().getInterfaces();
		result = searchOnInterfaces(method, annotationName, processor, visited, metaDepth, ifcs);
		if (result != null)
			return result;
		Class clazz = method.getDeclaringClass();
_L4:
		clazz = clazz.getSuperclass();
		if (clazz == null || java/lang/Object == clazz)
			break MISSING_BLOCK_LABEL_372;
		Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
		Method resolvedEquivalentMethod = BridgeMethodResolver.findBridgedMethod(equivalentMethod);
		result = searchWithFindSemantics(((AnnotatedElement) (resolvedEquivalentMethod)), annotationName, processor, visited, metaDepth);
		if (result != null)
			return result;
		break MISSING_BLOCK_LABEL_347;
		NoSuchMethodException nosuchmethodexception;
		nosuchmethodexception;
		result = searchOnInterfaces(method, annotationName, processor, visited, metaDepth, clazz.getInterfaces());
		if (result == null) goto _L4; else goto _L3
_L3:
		return result;
		Class clazz;
		Class aclass[];
		int k;
		if (!(element instanceof Class))
			break MISSING_BLOCK_LABEL_490;
		clazz = (Class)element;
		aclass = clazz.getInterfaces();
		result = aclass.length;
		k = 0;
_L5:
		Object result;
		if (k >= result)
			break MISSING_BLOCK_LABEL_440;
		Class ifc = aclass[k];
		result = searchWithFindSemantics(((AnnotatedElement) (ifc)), annotationName, processor, visited, metaDepth);
		if (result != null)
			return result;
		k++;
		  goto _L5
		Class superclass = clazz.getSuperclass();
		if (superclass == null || java/lang/Object == superclass)
			break MISSING_BLOCK_LABEL_490;
		result = searchWithFindSemantics(((AnnotatedElement) (superclass)), annotationName, processor, visited, metaDepth);
		if (result != null)
			return result;
		break MISSING_BLOCK_LABEL_490;
		Exception ex;
		ex;
		AnnotationUtils.handleIntrospectionFailure(element, ex);
		return null;
	}

	private static Object searchOnInterfaces(Method method, String annotationName, Processor processor, Set visited, int metaDepth, Class ifcs[])
	{
		Class aclass[];
		int i;
		int j;
		aclass = ifcs;
		i = aclass.length;
		j = 0;
_L3:
		if (j >= i) goto _L2; else goto _L1
_L1:
		Class iface;
		iface = aclass[j];
		if (!AnnotationUtils.isInterfaceWithAnnotatedMethods(iface))
			continue; /* Loop/switch isn't completed */
		Object result;
		Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
		result = searchWithFindSemantics(equivalentMethod, annotationName, processor, visited, metaDepth);
		if (result != null)
			return result;
		continue; /* Loop/switch isn't completed */
		NoSuchMethodException nosuchmethodexception;
		nosuchmethodexception;
		j++;
		  goto _L3
_L2:
		return null;
	}


}
